#ifndef AVALON_ASYNCTASKQUEUE_HPP
#define AVALON_ASYNCTASKQUEUE_HPP
#include <deque>
#include <vector>
#include "Avalon/Threading/Async.hpp"

namespace Avalon {
namespace Threading {

  /*! \class AsyncTaskQueue
   *  \brief Queues Tasks for asynchronous completion.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class AsyncTaskQueue {
    public:

      //! Constructs an AsyncTaskQueue.
      AsyncTaskQueue();

      ~AsyncTaskQueue();

      //! Adds a Task.
      /*!
        \param operation The operation to perform within the task.
      */
      void AddTask(const boost::function<void ()>& operation);

      //! Starts the next Task.
      /*!
        \return The result of the operation.
      */
      Threading::Async<void>::Ptr StartNextTask();

      //! Marks a Task as finished.
      /*!
        \param result The result of the Task.
      */
      void MarkTaskAsFinished(const Threading::Async<void>::Ptr& result);

      //! Returns the number of pending Tasks remaining.
      int GetPendingTaskCount() const;

      //! Returns the number of Tasks currently running.
      int GetRunningTaskCount() const;

      //! Returns <code>true</code> iff no Tasks remain pending or running.
      bool IsEmpty() const;

    private:
      std::deque<boost::function<void ()> > m_pendingTasks;
      std::vector<Threading::Async<void>::Ptr> m_runningTasks;
  };
}
}

#endif // AVALON_ASYNCTASKQUEUE_HPP
